! **************************************************************************** !
! Module mesh                                                                  !
!                                                                              !
! Description:                                                                 !
!   This module defines a series of types as being the building block of mesh. !
!   Other modules can use this module to be aware  of the  components of mesh. !
!                                                                              !
! Author:                                                                      !
!   * DONG Li, dongli@lasg.iap.ac.cn                                           !
!                                                                              !
! Programming record:                                                          !
!   * created in 2010/04/05                                                    !
! **************************************************************************** !

module mesh

    use phy_state

    implicit none

    ! ------------------------------------------------------------------- Grid !
    type grid_type
        real, allocatable :: x(:)
        type(phy_state_type) pstate
    end type grid_type
    
    ! ------------------------------------------------------------------- Edge !
    type edge_type
        integer num_vertex
        integer, allocatable :: local_vertex_index(:)
        real, allocatable :: norm(:)
    end type edge_type

    ! ------------------------------------------------------------------- Cell !
    type base_cell_type
        integer num_vertex
        real, allocatable :: vertex_x(:,:)
        integer num_neighb_cell
        integer, allocatable :: neighb_cell_index(:)
        integer num_edge
        type(edge_type), allocatable :: edges(:)
    end type base_cell_type

    type, extends(base_cell_type) :: cell_type
        integer, allocatable :: vertex_index(:)
        logical, allocatable :: is_neighb_cell_far(:,:)
    end type cell_type

    type, extends(base_cell_type) :: boundary_cell_type
        real, allocatable :: norm(:)
        integer boundary_class
    end type boundary_cell_type

    ! ------------------------------------------------------------------------ !
    
    integer num_dim
    integer mesh_class

    integer num_grid
    type(grid_type), allocatable :: grids(:)
    integer num_cell
    type(cell_type), allocatable :: cells(:)

    logical is_domain_regular
    logical is_mesh_uniform

    ! Only active when domain is irregular
    integer num_boundary_cell
    type(boundary_cell_type), allocatable :: boundary_cells(:)
    ! Only active when domain is regular
    integer, allocatable :: num_grid_(:)
    integer, allocatable :: num_cell_(:)
    real, allocatable :: boundary_x(:,:)
    real, allocatable :: span(:)
    integer, allocatable :: num_slice_cell(:)
    integer, allocatable :: boundary_class(:,:)
    ! Only active when domain is regular and mesh is uniform
    real, allocatable :: dx(:)

end module mesh
